﻿/***********************************************
 * ここの関数たちは速度の関係で後々ひとつの関数にします。
 * 関数別になっているのはデバッグがやりやすいからです。
 * 
 * 
 * //んで、２つ以上のクラスに対応するために最短一致にするのと、
 * //なんか消えるバグをけす。Matchるーぷにする。
 * 上はもうできました。
 * 
 * 後は...クラス読み取りのとき、一番初めのクラス取っちゃうのを直す。きっと。
 * 
 * 
 * 
 * 2011-05-03
 * Comit By Swallow.
 *
***********************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

class Optimization
{
    static public void Proc(ref string Code)//メインプロセス
    {

        //Optimization.Class(ref Code);//クラス処理

        Optimization.StartSign(ref Code);
        Optimization.EndSign(ref Code);//]　を　];　に変更する
        Optimization.Semicolon(ref Code);// ; の一つ前にスペースを挿入する
        Optimization.Colon(ref Code);// : の前後にスペースを挿入する

        Optimization.Atmark(ref Code);

        Optimization.DoubleDot(ref Code);//ダブルドット処理
        Optimization.Dot(ref Code);//ドット処理

        Optimization.PlusPlus(ref Code);//++処理
        Optimization.Plus(ref Code);//+処理
        Optimization.PlusEqual(ref Code);//+=処理
        Optimization.MinusMinus(ref Code);//--処理

        Optimization.Minus(ref Code);//-処理
        Optimization.MinusEqual(ref Code);//-=処理

        Optimization.Divide(ref Code);// /処理
        Optimization.DivideEqual(ref Code);// /=処理

        Optimization.Multiply(ref Code); // *処理
        Optimization.MultiplyEqual(ref Code);// *= 処理

        Optimization.Percent(ref Code);// %処理
        Optimization.PercentEqual(ref Code);// %= 処理

        Optimization.Pow(ref Code);// ^ の処理

        Optimization.Variable(ref Code); // 変数の初期化関連の処理

        Optimization.Parentheses(ref Code); // ( ) の処理

        Optimization.Greater(ref Code);// > の処理
        Optimization.GreaterEqual(ref Code);// >= の処理
        Optimization.GreaterGreater(ref Code);

        Optimization.Less(ref Code);// < の処理
        Optimization.LessEqual(ref Code);// <= の処理
        Optimization.LessLess(ref Code);// << の処理

        Optimization.Equal(ref Code);// = の処理

        Optimization.And(ref Code); // &の処理
        Optimization.Or(ref Code);// | の処理

        Optimization.EqualEqual(ref Code);// == の処理
        Optimization.ExclamationMarkEqual(ref Code);// !=　の処理

        Optimization.AndAnd(ref Code);// && の処理
        Optimization.OrOr(ref Code);    // ||　の処理
       
    }

    static public void Semicolon(ref string Code) // ;
    {
        Code = Regex.Replace(Code, ";", " ; ");
    }
    #region 念のためあるコード
    /*
    static public void Func(ref string Code)
    {
        Code = Regex.Replace(Code, "#Function", "#Function;");
        Code = Regex.Replace(Code, "#EndFunc", "#EndFunc;");
    }
     * */
    #endregion

    static public void EndSign(ref string Code) // ]
    {
        Code = Regex.Replace(Code, "]", "]; ");
    }
    static public void StartSign(ref string Code) // [
    {
        Code = Regex.Replace(Code, @"\[", " [ ");
    }

    static public void Colon(ref string Code)// :
    {
        Code = Regex.Replace(Code, ":", " : ");
    }

    static public void DoubleDot(ref string Code)// ..
    {
      Code = Regex.Replace(Code, @"\.\.", " .. ");
    }

    static public void Dot(ref string Code)// .
    {
        Regex r = new Regex(@"(?<N>[^\.])\.(?<B>[^\.])");
        Code = r.Replace(Code, "${N} . ${B}");
    }

    static public void PlusPlus(ref string Code)// ++
    {
        Regex r = new Regex(@"\+\+");
        Code = r.Replace(Code, "+=1");
    }

    static public void Plus(ref string Code)// +
    {
        Regex r = new Regex(@"(?<A>[^+])\+(?<B>[^=])");
        Code = r.Replace(Code, "${A} + ${B}");
    }
    static public void PlusEqual(ref string Code)// +=
    {
        Regex r = new Regex(@"\+=");
        Code = r.Replace(Code, " += ");

        r = new Regex(@"(?<Name>[ \w]+)\s\+=\s(?<Names>.+?)");//x = x + y

        Code = r.Replace(Code, @" ${Name} = ${Name} + ${Names} ");

    }

    static public void MinusMinus(ref string Code)// --
    {
        Regex r = new Regex(@"\-\-");//--
        Code = r.Replace(Code, "-=1");
    }

    static public void Minus(ref string Code) //-
    {
        Regex r = new Regex(@"(?<A>[^+])\-(?<B>[^=])");//xx-xx
        Code = r.Replace(Code, "${A} - ${B}");
    }
    static public void MinusEqual(ref string Code)// -=
    {
        Regex r = new Regex(@"\-=");
        Code = r.Replace(Code, " -= ");

        r = new Regex(@"(?<Name>[ \w]+)\s\-=\s(?<Names>.+?)");//x = x - y
        Code = r.Replace(Code, @" ${Name} = ${Name} - ${Names} ");
    }
    static public void Multiply(ref string Code)//*
    {
        Regex r = new Regex(@"(?<A>[^+])\*(?<B>[^=])");
        Code = r.Replace(Code, "${A} * ${B}");
    }

    static public void MultiplyEqual(ref string Code)// *=
    {
        Regex r = new Regex(@"\*=");
        Code = r.Replace(Code, " *= ");

        r = new Regex(@"(?<Name>[ \w]+)\s\*=\s(?<Names>.+?)");//x = x * y
        Code = r.Replace(Code, @" ${Name} = ${Name} * ${Names} ");
    }

    static public void Divide(ref string Code)// /=
    {
        Regex r = new Regex(@"(?<A>[^+])\/(?<B>[^=])");
        Code = r.Replace(Code, "${A} / ${B}");
    }

    static public void DivideEqual(ref string Code)// /=
    {
        Regex r = new Regex(@"\/=");
       Code = r.Replace(Code, " /= ");
        r = new Regex(@"(?<Name>[ \w]+)\s\/=\s(?<Names>.+?)");//x = x / y
        Code = r.Replace(Code, @" ${Name} = ${Name} / ${Names} ");

    }

    static public void Percent(ref string Code)// %
    {
        Regex r = new Regex(@"(?<A>[^+])\%(?<B>[^=])");
        Code = r.Replace(Code, "${A} % ${B}");
    }

    static public void PercentEqual(ref string Code)//%=
    {
        Regex r = new Regex(@"\%=");
        Code = r.Replace(Code, " %= ");

        r = new Regex(@"(?<Name>[ \w]+)\s\%=\s(?<Names>.+?)");//x = x / y

        Code = r.Replace(Code, @" ${Name} = ${Name} % ${Names} ");

    }

    static public void Parentheses(ref string Code)//( )
    {
        Regex r = new Regex(@"\(");
        Code = r.Replace(Code, " ( ");
        r = new Regex(@"\)");
        Code = r.Replace(Code, " ) ");
    }

    static public void Variable(ref string Code)// var xx = 0;
    {
        Regex r = new Regex(@"var\s+(?<Name>\w+)\s+=\s(?<Value>[\w\d]+)");

        Code = r.Replace(Code, @"(var ${Name} ; ${Name} = ${Value} )");
    }

    static public void Greater(ref string Code) // >
    {
        Regex r = new Regex(@"(?<Left>[^=><]+)\>(?<Right>[^=><]+)");
        Code = r.Replace(Code, "${Left} > ${Right}");
    }

    static public void Less(ref string Code) // <
    {
        Regex r = new Regex(@"(?<Left>[^=><]+)\<(?<Right>[^=><]+)");
        Code = r.Replace(Code, "${Left} < ${Right}");
    }

    static public void GreaterEqual(ref string Code) // >=
    {
        Regex r = new Regex(@"\>=");
        Code = r.Replace(Code, " >= ");
    }

    static public void LessEqual(ref string Code)// <=
    {
        Regex r = new Regex(@"\<=");
        Code = r.Replace(Code, " <= ");
    }

    static public void Equal(ref string Code)// =
    {
        Regex r = new Regex(@"(?<Left>[^=><]+?)\=(?<Right>[^=><]+?)");
        Code = r.Replace(Code, "${Left} = ${Right}");
    }

    static public void And(ref string Code) // &
    {
        Regex r = new Regex(@"(?<Left>[^=><]+?)\&(?<Right>[^=><]+?)");
        Code = r.Replace(Code, "${Left} & ${Right}");
    }

    static public void Or(ref string Code)// |
    {
        Regex r = new Regex(@"(?<Left>[^=><]+?)\|(?<Right>[^=><]+?)");
        Code = r.Replace(Code, "${Left} | ${Right}");
    }

    static public void EqualEqual(ref string Code) // ==
    {
        Regex r = new Regex(@"\=\=");//--
        Code = r.Replace(Code, " == ");
    }

    static public void ExclamationMarkEqual(ref string Code)// !=
    {
        Regex r = new Regex(@"\!\=");//--
        Code = r.Replace(Code, " != ");
    }

    static public void AndAnd(ref string Code)// !=
    {
        Regex r = new Regex(@"\&\&");//--
        Code = r.Replace(Code, " && ");
    }
    static public void OrOr(ref string Code)// !=
    {
        Regex r = new Regex(@"\|\|");//--
        Code = r.Replace(Code, " || ");
    }
    static public void Pow(ref string Code) // ^
    {
        Regex r = new Regex(@"(?<Left>[^=><]+?)\^(?<Right>[^=><]+?)");
        Code = r.Replace(Code, "${Left} ^ ${Right}");
    }

    static public void GreaterGreater(ref string Code)
    {
        Regex r = new Regex(@"\>\>");//--
        Code = r.Replace(Code, " >> ");

    }
    static public void LessLess(ref string Code)
    {
        Regex r = new Regex(@"\<\<");//--
        Code = r.Replace(Code, " << ");
    }
    static public void Atmark(ref string Code)
    {
        Regex r = new Regex(@"\@");//@~@
        Code = r.Replace(Code, " @ ");
    }

    #region 念のためにあるコード
    /*
    static public void Class(ref string Code)
    {
        List<string> Names = new List<string>();

        //string ComitCode = "";//最終適用用コード

        Regex r = new Regex(@"(?<All>##(?<Name>[^:]*?):.*?##.*\s*?(?<Left>\#Function)\s*?(?<Values>.*?)(?<Right>#EndFunc))");

        Match m = r.Match(Code);//照らしあわせる



        if (m.Success == false) return;
        do
        {


            string CodeTemp = "";//コード保管用
            string Name = m.Groups["Name"].Value.Replace(" ","");//クラス名の取得

             CodeTemp = m.Groups["Values"].Value;//値の読み取り(文)
            



            if (Names.IndexOf(Name) == -1)
            {
            }
            else
            {
                Regex rg = new Regex(@"(?:##)(?<Name>[^:]*?)(?:\:.*?##)(?=\s*"+")");
                Match rr = rg.Match(Code);
                Name = rr.Groups["Name"].Value.Replace(" ","");
                while (Names.IndexOf(Name) != -1)//ある間
                {
                    rr = rr.NextMatch();
                    Name = rr.Groups["Name"].Value.Replace(" ", "");
                }
            }
            Names.Add(Name);//追加
            
            




           

            

            Code = Code.Remove(m.Groups["Right"].Index, m.Groups["Right"].Length);
            Code = Code.Remove(m.Groups["Values"].Index, m.Groups["Values"].Length);//読み取り分削除
            Code = Code.Remove(m.Groups["Left"].Index, m.Groups["Left"].Length);

       

            Regex rs = new Regex(@"@(?<Value>.*?:.*?:.*?)\@");//関数名を探す

            CodeTemp = rs.Replace(CodeTemp, @"@${Value}:" + Name + "@");//置換



            Code += CodeTemp;//コードに追加

            Console.WriteLine("{0}\n\n\n\n", Code);


        } while ((m = r.Match(Code)).Success == true);

        //Code = ComitCode;


        Console.WriteLine(Code);
    }
     * */
    #endregion


}

